#include "dicom/handler/statfs_handler.h"

#include "surbasic/AccessToken.h"
#include "surbasic/surbasic.h"
#include "surbasic/Digestor.h"

#include <boost/bind.hpp>
#include <gwbase/base/util.h>
#include <gwbase/base/logging.h>
#include <gwbase/base/random.h>
#include <gwbase/base/thread.h>
#include <json/json.h>
#include "dicom/web_server.h"
#include "dicom/session.h"
#include "dicom/handler/handler_common.h"
#include "dicom/sync_manager.h"

namespace dicom {

static HttpHandler* CreateStatfsHander(onion_request* req,
                                       const DicomConf* conf) {
  return new StatfsHandler(req, conf);
}

void StatfsHandler::RegisterHandler(WebServer* s, const DicomConf* conf) {
  s->AddHandler("/api/statfs", "GET",
                boost::bind(CreateStatfsHander, _1, conf));
}

static void StatfsInfoToJson(Json::Value& v, const UserSpaceInfo& ui,
                             const CacheStat& cs) {
  v["allSpace"] = static_cast<Json::Int64>(ui.allSpace);
  v["allNonFileSpace"] = static_cast<Json::Int64>(ui.allNonFileSpace);
  v["singleNonFileSize"] = static_cast<Json::Int64>(ui.singleNonFileSize);
  v["usedSpace"] = static_cast<Json::Int64>(ui.usedSpace);
  v["creator"] = ui.creator;
  v["regTime"] =
      static_cast<Json::Int64>(ui.regTime.MicroSecondsSinceEpoch() / 1000000L);
  v["rootDirId"] = ui.rootDirId;
  v["userID"] = static_cast<Json::Int64>(ui.userID);

  v["cacheSpace"] = static_cast<Json::Int64>(cs.total_space);
  v["cacheUsed"] = static_cast<Json::Int64>(cs.used_space);
  v["cacheRemovable"] = static_cast<Json::Int64>(cs.removable_space);
}

int StatfsHandler::HandleRequest(onion_request* req, onion_response* resp) {
  Status s;
  CredentialPtr c;

  s = CheckToken(req, &c);
  if (!s.ok()) {
    SendSimpleResponse(resp, 401, "oauth error");
    return OCS_PROCESSED;
  }

  UserSpaceInfo uinfo;
  if (SDBasic::GetUserSpaceInfo(c->surdoc_key, uinfo) == false) {
    SendSimpleResponse(resp, 401, "failed to get user info from surcloud");
    return OCS_PROCESSED;
  }

  Json::Value v;
  v["code"] = 0;
  v["message"] = "success";

  Json::Value stat;
  CacheStat cs;
  GetGateway()->cache()->GetStat(&cs);
  StatfsInfoToJson(stat, uinfo, cs);

  v["stat"] = stat;
  SendJsonResult(resp, 200, v);
  return OCS_PROCESSED;
}
}
